package flex.cc.vehicle_svr.service.impl;

import com.alibaba.fastjson.JSONObject;
import flex.cc.PublicUtil;
import flex.cc.basicinformation.dao.ServiceProviderDataDao;
import flex.cc.basicinformation.entity.ServiceProviderDataEntity;
import flex.cc.basicinformation.entity.ServiceProviderEntity;
import flex.cc.common.Constants;
import flex.cc.common.utils.CommonUtils;
import flex.cc.order.manage.dao.OrderServiceProviderDao;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderServiceProviderEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.dto.vo.OrderMainVo;
import flex.cc.order.manage.enums.StatusEnum;
import flex.cc.order.manage.service.OrderMainService;
import flex.cc.order.manage.service.OrderTrackService;
import flex.cc.system.entity.DictCodeEntity;
import flex.cc.system.service.DictCodeService;
import flex.cc.vehicle_svr.service.CancelService;
import flex.cc.vehicle_svr.vo.ResponseVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author wkangle
 * @className CancelServiceImpl
 * @description 取消service
 * @time 2021-09-08 10:09:50
 */
@Service("cancelService")
public class CancelServiceImpl implements CancelService {
    private static final Logger logger = LoggerFactory.getLogger(CancelServiceImpl.class);

    @Autowired
    private OrderMainService orderMainService;
    @Autowired
    private OrderTrackService orderTrackService;
    @Autowired
    private DictCodeService dictCodeService;
    @Value("${pengda.cancelRescue}")
    private String cancelRescue;
    @Autowired
    private OrderServiceProviderDao orderServiceProviderDao;
    @Autowired
    private ServiceProviderDataDao serviceProviderDataDao;
    @Autowired
    private AsyncCancelService asyncCancelService;

    /**
	*
	* @author WANGCONG
	* 2021年10月22日上午9:37:52
	* @desc 上游操作---拦截取消
	* 规则：
	 	服务单不是派发失败状态，调对应下游取消接口；
		是派发失败状态，本地更新状态为服务取消。返回"取消成功"。
	*/
    @Override
    public String cancelOrder(Map<String, Object> requestBodyMap) throws ExecutionException, InterruptedException {
        Map<String, Object> params = new HashMap<>();
        params.put("ownerOrderNo", PublicUtil.isNotEmpty(requestBodyMap.get("ownerOrderNo")) ? requestBodyMap.get("ownerOrderNo").toString() : null);
        OrderMainEntity orderMainEntity = orderMainService.getOneByParams(params);
        String sourceCode = orderMainEntity.getSourceName();
        DictCodeEntity dictCodeEntity = dictCodeService.searchAllCodeByTypeCode("sourceName", sourceCode, 0, null); // 取消接口的操作人是渠道商名称 TODO
        String sourceName01 = dictCodeEntity.getValue();
        if (PublicUtil.isNotEmpty(orderMainEntity)) {
            String orderNo = orderMainEntity.getOrderNo();
            if (PublicUtil.isNotEmpty(orderNo)) {
            	if( "00".equals(orderMainEntity.getStatus()) ){ //派发失败状态---本地更新状态为服务取消。返回"取消成功"
//            		orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                    // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
            		saveTrack(orderNo, "13",
                            PublicUtil.isNotEmpty(requestBodyMap.get("cancelReason")) ? requestBodyMap.get("cancelReason").toString() : null,
                            "09", null, new Date(), sourceName01);
            		return "{\"resultCode\":\"1\",\"message\":\"取消失败：服务单未派发\"}";
            	}else if (!"08".equals(orderMainEntity.getStatus()) && !"09".equals(orderMainEntity.getStatus()) && !"00".equals(orderMainEntity.getStatus())
                        && !"10".equals(orderMainEntity.getStatus()) && !"11".equals(orderMainEntity.getStatus())) { // 08-已完成 09-服务取消 10-取消有费用 11-取消无费用
                    requestBodyMap.put("orderNo", orderNo);
                    // 服务单轨迹表
                    // 取消备注；服务取消
                    // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                    saveTrack(orderNo, "13",
                            PublicUtil.isNotEmpty(requestBodyMap.get("cancelReason")) ? requestBodyMap.get("cancelReason").toString() : null,
                            "09", null, new Date(), sourceName01);
                    // 调用下游取消接口
                    Map<String, Object> info = new HashMap<>();
            		info.put("orderNo", orderMainEntity.getOrderNo());
            		OrderServiceProviderEntity orderServiceProviderEntity = orderServiceProviderDao.getOneByParams(info);
            		String servicerId = orderServiceProviderEntity.getServerId();//服务商Id
                    Map<String, String> servicerParam = new HashMap<>();
                	servicerParam.put("servicerId", servicerId);
                	List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
                	String cancelUrl = "";
                	for(int i=0; i<urlList.size(); i++){
                		if(Constants.cancelRescue.equals(urlList.get(i).getUrlType())){
                			cancelUrl = urlList.get(i).getUrl();
                			break;
                		}
                	}
                	if(PublicUtil.isEmpty(cancelUrl)){
                        // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                		saveTrack(orderMainEntity.getOrderNo(), "13", "取消失败，未找到服务商取消接口地址", "09", null, new Date(), sourceName01);
                        return "{\"resultCode\":\"1\",\"message\":\"取消失败，未找到服务商取消接口地址\"}";
                	}

                	// 2022-01-04 15:06:35 上游取消：异步请求下游取消接口三次，若三次都未成功，则不再进行接口请求；若第二次请求返回成功，则不进行第三次请求
                    Future<String> future = asyncCancelService.asyncCancelOrder(requestBodyMap, cancelUrl, orderMainEntity, sourceName01);
                    return future.get();
                    //String cancelRescueResult = this.cancelRescue(cancelUrl, requestBodyMap);
                    //logger.info("上游取消结果 ==> cancelRescueResult: " + cancelRescueResult);
                    //if (cancelRescueResult != null) {
                    //    JSONObject resultObject = JSONObject.parseObject(cancelRescueResult);
                    //    Integer resultCode = Integer.valueOf(PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null);
                    //    logger.info("取消结果 ==> resultCode: " + resultCode);
                    //    String message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;
                    //    logger.info("取消结果 ==> message: " + message);
                    //    if (resultCode == 0) {
                    //        // 下游取消成功，更新车服平台服务单状态为服务取消
                    //        // 2022-01-04 14:16:17 到店类服务需求取消优化：上游发起取消时不用调用上游取消通知接口，此处为了区分给服务单主表新增字段cancel_channel取消渠道：1-上游，2-下游，3-车服，4-C端
                    //        // orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                    //        orderMainEntity.setCancelChannel("1");
                    //        orderMainEntity.setStatus("09");
                    //        orderMainEntity.setUpdateTime(new Date());
                    //        orderMainEntity.setUpdater(sourceName01);
                    //        orderMainService.update(orderMainEntity);
                    //        logger.info("取消备注：下游取消成功，更新车服平台服务单状态为服务取消，并记录救援轨迹.......");
                    //        // 服务单轨迹表
                    //        // 取消备注；服务取消；任务结束
                    //        saveTrack(orderNo,
                    //                "03",
                    //                "下游取消成功",
                    //                "09",
                    //                StatusEnum.getName("09"),
                    //                new Date(),
                    //                sourceName01);
                    //
                    //    } else {
                    //        // 下游取消失败，记录原因
                    //        logger.info("取消备注：下游取消失败.......... " + message);
                    //        // 救援轨迹；服务取消；任务结束
                    //        saveTrack(orderNo,
                    //                "03",
                    //                "下游取消失败：" + message,
                    //                "09",
                    //                StatusEnum.getName("09"),
                    //                new Date(),
                    //                sourceName01);
                    //
                    //    }
                    //    return cancelRescueResult;
                    //} else {
                    //    // 下游取消失败，记录原因
                    //    logger.info("取消备注：下游取消失败：取消接口请求异常");
                    //    // 救援轨迹；服务取消；任务结束
                    //    saveTrack(orderNo,
                    //            "03",
                    //            "下游取消失败：取消接口请求异常",
                    //            "09",
                    //            StatusEnum.getName("09"),
                    //            new Date(),
                    //            sourceName01);
                    //    return "{\"resultCode\":\"1\",\"message\":\"取消失败，取消接口请求异常\"}";
                    //}
                } else if ("10".equals(orderMainEntity.getStatus())) {
                    // 服务单轨迹表
                    logger.info(orderNo + "取消备注：服务单状态为取消有费用，不可取消.........");
                    // 取消备注；服务取消
                    // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                    saveTrack(orderNo, "13", "服务单号为" + orderNo + "的服务单状态为取消有费用，不可取消",
                            "10", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为取消有费用，不可取消\"}";
                } else if ("11".equals(orderMainEntity.getStatus())) {
                    // 服务单轨迹表
                    logger.info(orderNo + "取消备注：服务单状态为取消无费用，不可取消.........");
                    // 取消备注；服务取消
                    // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                    saveTrack(orderNo, "13", "服务单号为" + orderNo + "的服务单状态为取消无费用，不可取消",
                            "11", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为取消无费用，不可取消\"}";
                } else{ // 08-已完成 09-服务取消
                    // 服务单轨迹表
                    logger.info(orderNo + "取消备注：服务单状态为已完成或服务取消，不可取消.........");
                    // 取消备注；服务取消
                    // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                    saveTrack(orderNo, "13", "服务单号为" + orderNo + "的服务单状态为已完成或服务取消，不可取消",
                            "09", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为已完成或服务取消，不可取消\"}";
                }
            } else {
                // 服务单轨迹表
                logger.info("取消备注：服务单号不存在.........");
                // 取消备注；服务取消
                // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
                saveTrack(orderNo, "13", "服务单号不存在", "09", null, new Date(), sourceName01);
                return "{\"resultCode\":\"1\",\"message\":\"服务单号不存在，取消失败\"}";
            }
        } else {
            // 服务单轨迹表
            logger.info("取消备注：渠道来源单号不存在............");
            // 取消备注；服务取消
            // 2022-03-14 10:39:54【2.2-服务包配置需求】救援单轨迹表新增备注类型：渠道商催单12、渠道商取消13
            saveTrack(PublicUtil.isNotEmpty(orderMainEntity) ? orderMainEntity.getOrderNo() : null,
                    "13", "渠道来源单号不存在", "09", null, new Date(), sourceName01);
            return "{\"resultCode\":\"1\",\"message\":\"渠道来源单号不存在，取消失败\"}";
        }
    }


    @Override
	public String cancelInfo(OrderMainVo orderMain) throws ExecutionException, InterruptedException {
		if(PublicUtil.isEmpty(orderMain.getOwnerOrderNo())) {
			return "{\"resultCode\":\"1\",\"message\":\"来源单号不存在，取消失败\"}";
		}
        if(PublicUtil.isEmpty(orderMain.getCancelReason())) {
        	return "{\"resultCode\":\"1\",\"message\":\"取消原因为空，取消失败\"}";
		}
        String remark="";
        if(!PublicUtil.isEmpty(orderMain.getCancelRemark())) {
        	remark=orderMain.getCancelRemark();
        }

        Map<String, Object> requestBodyMap =new HashMap<String, Object>();
        Map<String, Object> params = new HashMap<>();
        params.put("ownerOrderNo",orderMain.getOwnerOrderNo());
        OrderMainEntity orderMainEntity = orderMainService.getOneByParams(params);
        String sourceCode = orderMainEntity.getSourceName();
        DictCodeEntity dictCodeEntity = dictCodeService.searchAllCodeByTypeCode("sourceName", sourceCode, 0, null); // 取消接口的操作人是渠道商名称 TODO
        String sourceName01 = dictCodeEntity.getValue();

        if (PublicUtil.isNotEmpty(orderMainEntity)) {
            String orderNo = orderMainEntity.getOrderNo();
            if (PublicUtil.isNotEmpty(orderNo)) {
            	if( "00".equals(orderMainEntity.getStatus()) ){ //派发失败状态---本地更新状态为服务取消。返回"取消成功"
            		orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
            		 saveTrack(orderNo,"06","客户取消成功"+orderMain.getCancelReason().split(";")[1]+remark,"09",StatusEnum.getName("09"),new Date(),sourceName01);
            		return "{\"resultCode\":\"0\",\"message\":\"取消成功\"}";
            	} else if (!"08".equals(orderMainEntity.getStatus()) && !"09".equals(orderMainEntity.getStatus()) && !"00".equals(orderMainEntity.getStatus())
                        && !"10".equals(orderMainEntity.getStatus()) && !"11".equals(orderMainEntity.getStatus())) { // 08-已完成 09-服务取消 10-取消有费用 11-取消无费用
                    requestBodyMap.put("orderNo", orderNo);
                    requestBodyMap.put("cancelReason", orderMain.getCancelReason().split(";")[1]);
                    // 服务单轨迹表
                    // 取消备注；服务取消
                    ///veTrack(orderNo, "06",orderMain.getCancelReason().split(";")[1]+remark,"09", null, new Date(), sourceName01);
                    // 调用下游取消接口
                    Map<String, Object> info = new HashMap<>();
                    info.put("orderNo", orderMainEntity.getOrderNo());
                    OrderServiceProviderEntity orderServiceProviderEntity = orderServiceProviderDao.getOneByParams(info);
                    String servicerId = orderServiceProviderEntity.getServerId();//服务商Id
                    Map<String, String> servicerParam = new HashMap<>();
                    servicerParam.put("servicerId", servicerId);
                    List<ServiceProviderDataEntity> urlList = serviceProviderDataDao.queryListByYwId(servicerId);
                    String cancelUrl = "";
                    for(int i=0; i<urlList.size(); i++){
                        if(Constants.cancelRescue.equals(urlList.get(i).getUrlType())){
                            cancelUrl = urlList.get(i).getUrl();
                            break;
                        }
                    }
                    if(PublicUtil.isEmpty(cancelUrl)){
                        saveTrack(orderMainEntity.getOrderNo(), "06", "客户取消失败，未找到服务商取消接口地址", "09", null, new Date(), sourceName01);
                        return "{\"resultCode\":\"1\",\"message\":\"客户取消失败，未找到服务商取消接口地址\"}";
                    }

                    // 2022-01-04 15:06:35 C端取消：异步请求下游取消接口三次，若三次都未成功，则不再进行接口请求；若第二次请求返回成功，则不进行第三次请求
                    Future<String> future = asyncCancelService.asyncCancelInfo(requestBodyMap, cancelUrl, orderMainEntity, orderMain, sourceName01, remark);
                    return future.get();
                    //String cancelRescueResult = this.cancelRescue(cancelUrl, requestBodyMap);
                    //logger.info("客户取消结果 ==> cancelRescueResult: " + cancelRescueResult);
                    //if (cancelRescueResult != null) {
                    //    JSONObject resultObject = JSONObject.parseObject(cancelRescueResult);
                    //    Integer resultCode = Integer.valueOf(PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null);
                    //    logger.info("客户取消结果 ==> resultCode: " + resultCode);
                    //    String message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;
                    //    logger.info("客户取消结果 ==> message: " + message);
                    //    if (resultCode == 0) {
                    //        // 下游取消成功，更新车服平台服务单状态为服务取消
                    //        orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                    //        logger.info("救援轨迹：客户取消成功，更新车服平台服务单状态为服务取消，并记录救援轨迹.......");
                    //        // 服务单轨迹表
                    //        // 取消备注；服务取消；任务结束
                    //      saveTrack(orderNo,"06","客户取消成功"+orderMain.getCancelReason().split(";")[1]+remark,"09",StatusEnum.getName("09"),new Date(),sourceName01);
                    //    } else {
                    //        // 客户取消失败，记录原因
                    //        logger.info("救援轨迹：客户取消失败.......... " + message);
                    //        // 救援轨迹；服务取消；任务结束
                    //        saveTrack(orderNo,"06","客户取消失败：" + message,"09",StatusEnum.getName("09"),new Date(),sourceName01);
                    //    }
                    //    return cancelRescueResult;
                    //} else {
                    //    // 客户取消失败，记录原因
                    //    logger.info("救援轨迹：客户取消失败：取消接口请求异常");
                    //    // 救援轨迹；服务取消；任务结束
                    //    saveTrack(orderNo, "06", "客户取消失败：取消接口请求异常", "09", StatusEnum.getName("09"), new Date(),sourceName01);
                    //    return "{\"resultCode\":\"1\",\"message\":\"下游取消失败：取消接口请求异常\"}";
                    //}
                } else if ("10".equals(orderMainEntity.getStatus())) {
                    // 服务单轨迹表
                    logger.info("取消备注：服务单状态为取消有费用，不可取消.........");
                    // 取消备注；服务取消
                    saveTrack(orderNo, "03", "服务单号为" + orderNo + "的服务单状态为取消有费用，不可取消",
                            "10", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为取消有费用，不可取消\"}";
                } else if ("11".equals(orderMainEntity.getStatus())) {
                    // 服务单轨迹表
                    logger.info("取消备注：服务单状态为取消无费用，不可取消.........");
                    // 取消备注；服务取消
                    saveTrack(orderNo, "03", "服务单号为" + orderNo + "的服务单状态为取消无费用，不可取消",
                            "11", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为取消无费用，不可取消\"}";
                } else{ // 08-已完成 09-服务取消
                    // 服务单轨迹表
                    logger.info("取消备注：服务单状态为已完成或服务取消，不可取消.........");
                    // 取消备注；服务取消
                    saveTrack(orderNo, "03", "服务单号为" + orderNo + "的务单状态为已完成或服务取消，不可取消",
                            "09", null, new Date(), sourceName01);
                    return "{\"resultCode\":\"1\",\"message\":\"服务单号为" + orderNo + "的服务单状态为已完成或服务取消，不可取消\"}";
                }
            } else {
                // 服务单轨迹表
                logger.info("取消备注：服务单号不存在.........");
                // 取消备注；服务取消
                saveTrack(orderNo, "06", "服务单号不存在", "09", null, new Date(), sourceName01);
                return "{\"resultCode\":\"1\",\"message\":\"服务单号不存在，取消失败\"}";
            }
        }else {
            // 服务单轨迹表
            logger.info("取消备注：渠道来源单号不存在............");
            // 取消备注；服务取消
            saveTrack(PublicUtil.isNotEmpty(orderMainEntity) ? orderMainEntity.getOrderNo() : null,
                    "06", "渠道来源单号不存在", "09", null, new Date(), sourceName01);
            return "{\"resultCode\":\"1\",\"message\":\"渠道来源单号不存在，取消失败\"}";
        }
	}



    /**
     * @description 根据条件保存轨迹
     * @param orderNo 服务单号
     * @param trackType 轨迹类型
     * @param trackDesc 轨迹描述
     * @param status 状态
     * @param serviceStatus 下游回传状态描述
     * @param currentDate 当前时间
     * @param sourceName01 操作人
     * @return
     * @author wkangle
     * @time 2021/10/09 0009 11:13
     * @exception/throws
     */
    private void saveTrack(String orderNo, String trackType, String trackDesc, String status, String serviceStatus, Date currentDate, String sourceName01){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setServiceStatus(serviceStatus);

        orderTrackEntity.setSynTime(PublicUtil.isNotEmpty(serviceStatus) ? currentDate : null); // 当serviceStatus不为空即该轨迹是“救援轨迹-任务结束”时，记操作时间为当前时间，用于展示在救援信息列表中，相当于状态回写接口报文中的操作时间。

        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(sourceName01);
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(sourceName01);
        orderTrackService.insert(orderTrackEntity);
    }

    /**
     * 取消
     * */
    @Override
    public String cancelRescue(String cancel_rescue_url, Map<String, Object> requestBodyMap){
        Map<String, Object> param = new HashMap<String, Object>(){{
            put("orderNo", requestBodyMap.get("orderNo"));
            put("cancelReason", requestBodyMap.get("cancelReason"));
        }};
        logger.info("cancelRescue: " + param);
        return CommonUtils.doPost(cancel_rescue_url, CommonUtils.toJSONString(param));
    }

}
